﻿using ApplicationBase.Core.Domain;

namespace IdentityService.Domain.Aggregates.PermitAggregate
{
    public class Permit : Entity, IAggregateRoot
    {
        public long Id { get; init; }
        public string Name { get; private set; }
        public string? Description { get; private set; }
        public long? ParentId { get; set; }
        public IList<Permit> Children { get; set; } = new List<Permit>();

        public Permit(long id, string name, string? description = "")
            => (Id, Name, Description) = (id, name, description);

        public void Modify(string name, string description)
            => (Name, Description) = (name, description);

        public bool AddDescendant(Permit permit)
        {
            if (permit.ParentId == Id)
            {
                Children.Add(permit);
                return true;
            }
            else
            {
                foreach (var child in Children)
                {
                    if (child.AddDescendant(permit)) return true;
                }
                return false;
            }
        }

        public Permit? FindDescendantById(long id)
        {
            if (Children.Count == 0) return null;

            foreach (var child in Children)
            {
                if (child.Id == id) return child;
                else
                {
                    var result = child.FindDescendantById(id);
                    if (result != null) return result;
                }
            }

            return null;
        }

        public Permit? FindDescendantByName(string name)
        {
            if (Children.Count == 0) return null;
            
            foreach (var child in Children)
            {
                if(child.Name == name) return child;
                else
                {
                    var result = child.FindDescendantByName(name);
                    if(result != null) return result;
                }
            }

            return null;
        }

        public List<string> GetAllDescendantName()
        {
            var list = new List<string> { Name };
            LoadAllChildrenName(list);

            return list;
        }

        private void LoadAllChildrenName(List<string> list)
        {
            foreach (var child in Children)
            {
                list.Add(child.Name);
                if(child.Children.Count > 0)
                {
                    child.LoadAllChildrenName(list);
                }
            }
        }
    }
}
